package edu.sias.hyzn.service.impl;

import edu.sias.common.core.domain.model.LoginUser;
import edu.sias.common.utils.SecurityUtils;
import edu.sias.common.utils.file.FileUploadUtils;
import edu.sias.hyzn.config.PythonServiceConfig;
import edu.sias.hyzn.domain.Visit;
import edu.sias.hyzn.domain.VisitDiagnosis;
import edu.sias.hyzn.exception.InvalidFileFormatException;
import edu.sias.hyzn.exception.PythonNoResponseException;
import edu.sias.hyzn.mapper.PatientMapper;
import edu.sias.hyzn.mapper.VisitDiagnosisMapper;
import edu.sias.hyzn.mapper.VisitMapper;
import edu.sias.hyzn.service.IEyeDiagnosisService;
import edu.sias.hyzn.vo.EyeAnalysisResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class EyeDiagnosisService implements IEyeDiagnosisService {
    private static PythonServiceConfig pythonServiceConfig;
    private final RestTemplate restTemplate = new RestTemplate();
    private final VisitMapper visitMapper;
    private final VisitDiagnosisMapper visitDiagnosisMapper;

    @Autowired
    public EyeDiagnosisService(PythonServiceConfig pythonServiceConfig,
                               VisitMapper visitMapper, VisitDiagnosisMapper visitDiagnosisMapper) {
        EyeDiagnosisService.pythonServiceConfig = pythonServiceConfig;
        this.visitMapper = visitMapper;
        this.visitDiagnosisMapper = visitDiagnosisMapper;
    }

    public EyeAnalysisResult analysisAndSaveEyeImages(MultipartFile leftEyeFile, MultipartFile rightEyeFile, Long doctorId, String doctorName)
            throws IOException, InvalidFileFormatException, PythonNoResponseException {
        // 转换文件
        File leftEye = convertToFile(leftEyeFile);
        File rightEye = convertToFile(rightEyeFile);

        // 校验文件格式
        if (!isValidImageFormat(leftEye) || !isValidImageFormat(rightEye)) {
            throw new InvalidFileFormatException("文件格式错误，请上传正确的图片");
        }

        // 上传到阿里云 OSS
        String leftImgUrl = FileUploadUtils.uploadFileToAliYunOss(leftEye);
        String rightImgUrl = FileUploadUtils.uploadFileToAliYunOss(rightEye);

        // 发送请求到 Python 服务
        Map<String, Object> responseBody = sendToPythonService(leftEye, rightEye);

        // 删除临时文件
        leftEye.delete();
        rightEye.delete();

        // 解析诊断结果parseResponse
        List<VisitDiagnosis> visitDiagnosisList = parseResponse(responseBody);

        // 插入 visit 记录
        Visit visit = new Visit();
        visit.setUserId(doctorId);
        visit.setLeftImgUrl(leftImgUrl);
        visit.setRightImgUrl(rightImgUrl);
        visitMapper.insertVisit(visit); // 这一步会填充 visit.id

        // 插入 visit_diagnosis 记录
        HashMap<String, Double> predictions = new HashMap<>();
        String[] diasesList = {"Normal", "Diabetes", "Glaucoma", "Cataract", "AMD", "Hypertension", "Myopia", "Others"};
        for (VisitDiagnosis vd : visitDiagnosisList) {
            vd.setVisitId(visit.getId());
            visitDiagnosisMapper.insertVisitDiagnosis(vd);
            predictions.put(diasesList[vd.getDiseaseId()-1], vd.getProbability());
        }
        String analysisResult = parseDiagnosis((HashMap<String, Integer>)responseBody.get("diagnosis"));
        // 返回处理结果
        return new EyeAnalysisResult(doctorName, visit.getId(), leftImgUrl, rightImgUrl, analysisResult, predictions);
    }


    private Map<String, Object> sendToPythonService(File leftEye, File rightEye) throws PythonNoResponseException {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("left_eye", new FileSystemResource(leftEye));
        body.add("right_eye", new FileSystemResource(rightEye));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

        ResponseEntity<Map> response = restTemplate.exchange(pythonServiceConfig.getUrl(), HttpMethod.POST, requestEntity, Map.class);

        if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
            throw new PythonNoResponseException("请求 Python 服务器失败，HTTP 状态码：" + response.getStatusCode());
        }
        return response.getBody();
    }

    private boolean isValidImageFormat(File file) {
        String filename = file.getName().toLowerCase();
        return filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png");
    }

    private File convertToFile(MultipartFile file) throws IOException {
        File tempFile = File.createTempFile("upload_", "_" + file.getOriginalFilename());
        file.transferTo(tempFile);
        return tempFile;
    }

    private String parseDiagnosis(Map<String, Integer> diagnosis) {
        // 定义疾病映射表
        Map<String, String> diseaseMap = Map.of(
                "Diabetes", "糖尿病",
                "Glaucoma", "青光眼",
                "Cataract", "白内障",
                "AMD", "年龄相关性黄斑病变",
                "Hypertension", "高血压",
                "Myopia", "近视",
                "Others", "其他疾病"
        );

        List<String> detectedDiseases = new ArrayList<>();
        boolean hasOthers = false;

        for (Map.Entry<String, Integer> entry : diagnosis.entrySet()) {
            if (entry.getValue() != null && (Integer) entry.getValue() == 1) {
                String diseaseKey = entry.getKey();
                if ("Normal".equals(diseaseKey)) {
                    return "健康"; // 如果是健康，直接返回
                }else if (diseaseMap.containsKey(diseaseKey)) {
                    detectedDiseases.add(diseaseMap.get(diseaseKey)); // 映射疾病名称
                }
            }
        }

        if (detectedDiseases.isEmpty() && !hasOthers) {
            return "未检测到疾病";
        }

        return String.join(", ", detectedDiseases);
    }
    private List<VisitDiagnosis> parseResponse(Map<String, Object> responseBody) {

        Map<String, Double> predict = (Map<String, Double>) responseBody.get("predictions");
        Map<String, Integer> diagnosis = (Map<String, Integer>) responseBody.get("diagnosis");

        /*
        * 	"predictions": {//概率值
                "Normal": 0.0372,  //正常
                "Diabetes": 0.0562,  //糖尿病
                "Glaucoma": 0.0035,  //青光眼
                "Cataract": 0.0024,  //白内障
                "AMD": 0.0187,  //AMD（年龄相关性黄斑病变）
                "Hypertension": 0.0054,  //高血压
                "Myopia": 0.0088,  //近视
                "Others": 0.9205  //其他疾病
            },
        * */
        //分别对应1,2,3,4,5,6,7,8
        String[] diasesList = {"Normal", "Diabetes", "Glaucoma", "Cataract", "AMD", "Hypertension", "Myopia", "Others"};
        int i = 1;
        List<VisitDiagnosis> visitDiagnosisList = new ArrayList<>();
        for (String disease : diasesList) {
            VisitDiagnosis vd = new VisitDiagnosis(0L, 0L, i, predict.get(disease), diagnosis.get(disease));
            visitDiagnosisList.add(vd);
            i++;
        }
        return visitDiagnosisList;
    }

}

